using System;
using System.Collections.Generic;
using System.Text;
using Autorun;

namespace Samples
{
    class StressTest : TaskBase
    {
        #region "Constants and Enums"
        private enum RunModes
        {
            Both = 0,
            ThreadSleep = 1,
            CPUConsume = 2
        }
        #endregion

        #region "Members"
        private System.Random myRandomizer;
        private int myCycles;
        private bool mShouldCrash;
        #endregion

        #region "Overriden methods"
        protected override void InitializeParameterList()
        {
            // === No parameters are expected ================================
        }
        
        protected override void PreProcess()
        {
            int seed;

            seed = ((int)DateTime.Now.Ticks & 2147483647);
            myRandomizer = new Random(seed);

            if ((myRandomizer.Next() % 10) == 0)
                throw new Exception("Exception during Pre-Process");
            else
            {
                myCycles = myRandomizer.Next(1, 60);
                mShouldCrash = ((myRandomizer.Next(1, 100) % 15) == 0);
            }
        }

        protected override void Process()
        {
            int cycles;
            int value;
            byte useThreadSleep;
            RunModes realRunMode;
            DateTime startTime;

            Notify(SeverityLevels.Info, String.Format("Running for {0} cycles (crash: {1})", myCycles, mShouldCrash));
            while (myCycles > 0)
            {
                useThreadSleep = (byte)(myRandomizer.Next() % 256);
                cycles = myRandomizer.Next(1, ((myCycles < 10 ? myCycles : 10)) | 1);

                realRunMode = (useThreadSleep < 200 ? RunModes.ThreadSleep : RunModes.CPUConsume);
                Notify(SeverityLevels.Info, String.Format("Remains: {0}, Processing: {1}, Mode: {2}", myCycles, cycles, realRunMode));

                switch (realRunMode)
                {
                    case RunModes.CPUConsume:
                        if (mShouldCrash == true)
                        {
                            value = myRandomizer.Next();
                            if ((value % cycles) == 0)
                                throw new Exception(String.Format("Exception during Process (Remaining={0}, Processing={1}, value={2})", myCycles, cycles, value));
                        }

                        startTime = DateTime.Now;
                        while (DateTime.Now.Subtract(startTime).TotalSeconds < cycles)
                        {
                        }
                        break;
                    case RunModes.ThreadSleep:
                        System.Threading.Thread.Sleep(cycles * 1000);
                        break;
                    default:
                        throw new Exception("Invalid run mode " + realRunMode);
                }

                myCycles -= cycles;
            }
        }

        protected override void PostProcess()
        {
            if ((myRandomizer.Next() % 10) == 0)
                throw new Exception("Exception during Post-Process");
        }
        #endregion
    }
}
